package org.punkliner.in;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.HashSet;
import java.util.Set;

import org.punkliner.out.Writer;

public class SmbListener extends Thread {

	private Set<Writer> writers = new HashSet<Writer>();

	public void run() {
		DatagramSocket ds;
		try {
			ds = new DatagramSocket(null);
			ds.setBroadcast(true);
			ds.setReuseAddress(true);
			ds.bind(new InetSocketAddress(138));
			ds.setSoTimeout(1000);
		} catch (SocketException e1) {
			e1.printStackTrace();
			return;
		}

		byte[] data = new byte[255];
		DatagramPacket dp = new DatagramPacket(data, data.length);
		while (true) {
			if (isInterrupted()) {
				break;
			}

			try {
				ds.receive(dp);
			} catch (SocketTimeoutException e1) {
				continue;
			} catch (IOException e1) {
				e1.printStackTrace();
				continue;
			}
			// String src_ip = dp.getAddress().getHostAddress();
			data = dp.getData();
			String st = new String(data);
			int index = st.toUpperCase().indexOf("\\MAILSLOT\\BROWSE");
			if ((index += 17) != 16 && (data[index] == 1 || data[index] == 15)) {
				byte nameHex[] = new byte[33];
				System.arraycopy(data, 14, nameHex, 0, 32);
				// String name = BTS(nameHex);
				int isServer = data[index + 24];
				isServer &= 2;
				isServer >>>= 1;
				// GregorianCalendar c = new GregorianCalendar();
				if (isServer == 1) {
					// System.out.println((new
					// StringBuilder()).append(src_ip).append("
					// (").append(name).append(") announced himself
					// (online)").append(" at ").append(new Date()).toString());
					try {
						for (Writer writer : writers) {
							writer.write(dp.getAddress());
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				} else {
					// System.out.println((new
					// StringBuilder()).append(src_ip).append("
					// (").append(name).append(") went offline").append(" at
					// ").append(new Date()).toString());
				}
			}
		}
		ds.close();
		for (Writer writer : writers) {
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static String BTS(byte data[]) {
		StringBuffer sb = new StringBuffer();
		for (int t = 1; t < data.length - 2; t += 2) {
			if (data[t] == 67 && data[t + 1] == 65)
				break;
			try {
				sb.append(new String(new byte[] { (byte) ((data[t] - 65 << 4) + (data[t + 1] - 65 & 0xf)) }, "cp866"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				System.exit(1);
			}
		}
		return sb.toString();
	}

	public void addWriter(Writer writer) {
		try {
			writer.open();
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		writers.add(writer);
	}
}
